﻿#include "measure_cricle.h"
#include "math.h"
#include "QTime"
#include "qdebug.h"
#include "QDir"
Measure_Cricle::Measure_Cricle()
{


}
//0是ok  1圆度不合格     2圆尺寸不合格  3内外不同心
int Measure_Cricle::M_Cricle(HObject img,bool saveImg,HTuple &In_Round,HTuple &Out_Round,HTuple &In_Len,HTuple &Out_Len, HObject &Out_Img)
{

  
    In_Round=0;
    Out_Round=0;
    In_Len=0;
    Out_Len=0;
    Distance=0;

    //圆度
    int Round_Error=0;
    //长度
    int Length_Error=0;
    //同心
    int Center_Error=0;

    int flag=0;

    M_Cricle_Index++;
    QString OK_Path=QDir::currentPath()+"/Pic/ccd1/OK/"+QString::number(M_Cricle_Index)+".bmp";
    QString NG_Path=QDir::currentPath()+"/Pic/ccd1/NG/"+QString::number(M_Cricle_Index)+".bmp";
    QString Abnormal_Path=QDir::currentPath()+"/Pic/ccd1/Abnormal/"+QString::number(M_Cricle_Index)+".bmp";



    //存图 0 不存  1 存图
    bool bSaveImage = bool(para1.Save_Image);
    try
    {

        HObject  ROI_Img, ROI, Region_Out,Region_In,Region,RegionFillUp;
        HObject  In_Contour, Out_Contour, RegionComplement;

        HObject In_Region,S_In_Region;

        HTuple  Value_Out,Value_In,OutCir,InCir;
        HTuple  Area, Row;
        HTuple  Column, In_Radius, In_Para, In_MetrologyHandle;
        HTuple  Index1, Parameter, Phi, StartPhi, EndPhi;
        HTuple  PointOrder, In_Area, In_Row, In_Col;
        HTuple  PointOrder1, In_Circularity, Out_Radius;
        HTuple  Out_Para, Out_MetrologyHandle, Out_Area;
        HTuple  Out_Row, Out_Col, Out_Circularity;
        HTuple  In_Length1, In_Length2, In_Length;
        HTuple  Out_Length1, Out_Length2, Out_Length;

        HTuple In_Num;
        Out_Circularity=0;
        In_Circularity=0;
        In_Length=0;
        Out_Length=0;
        Out_Col=0;
        Out_Row=0;
        In_Col=0;
        In_Row=0;
        InRoundFlag=true;
        OutRoundFlag=true;
        CricleFlag=true;
        InlenFlag=true;
        OutlenFlag=true;
        ////************根据不同型号的产品，参数也不一致
        ////换算比例=（实际尺寸/像素大小）
        //float Scale=0.0097189;
        ////内圆标准尺寸
        //float In_Size=0.7;
        ////外圆标准尺寸
        //float Out_Size=2.24;
        ////内圆标准偏差
        //float In_Deviation=0.04;
        ////外圆标准偏差
        //float Out_Deviation=0.04;
        ////是否同心标准，单位像素点
        //float Cricle_Deviation=3;
        ////内圆度标准1
        //float In_Roundness1 = 0.85;
        ////内圆度标准2
        //float In_Roundness2 = 0.9;
        ////外圆度标准1
        //float Out_Roundness1 = 0.9;
        ////外圆度标准2
        //float Out_Roundness2 = 0.99;
        ////外圆形尺寸
        //float Out_Circle_Size=150470;
        ////内圆形尺寸
        //float In_Circle_Size=16480;


        
	    //换算比例=（实际尺寸/像素大小）
	    float Scale = para1.Scale;
		//内圆标准尺寸
		float In_Size = para1.In_Size;
        //内圆补偿值
        float OffSet_In_Size=para1.OffSet_In_Size;
		//外圆标准尺寸
		float Out_Size = para1.Out_Size;
        //外圆补偿值
        float OffSet_Out_Size=para1.OffSet_Out_Size;


        //内圆上限标准偏差
        float Up_In_Deviation = para1.Up_In_Deviation;
        //内圆下限标准偏差
        float Down_In_Deviation = para1.Down_In_Deviation;
        //外圆上限标准偏差
        float Up_Out_Deviation = para1.Up_Out_Deviation;
        //外圆下限标准偏差
        float Down_Out_Deviation = para1.Down_Out_Deviation;
		//是否同心标准，单位像素点
		float Cricle_Deviation = para1.Cricle_Deviation;
        //内圆度标准1
        float In_Roundness1 = para1.In_Roundness1;
        //内圆度标准2
        float In_Roundness2 = para1.In_Roundness2;
        //外圆度标准1
        float Out_Roundness1 = para1.Out_Roundness1;
        //外圆度标准2
        float Out_Roundness2 = para1.Out_Roundness2;
		//外圆形尺寸
		float Out_Circle_Size = para1.Out_Circle_Size;
		//内圆形尺寸
		float In_Circle_Size = para1.In_Circle_Size;

        
        


//		GenRectangle1(&ROI, 22, 214, 1501, 2050);
        GenRectangle1(&ROI, m_place.x1, m_place.y1,  m_place.x2, m_place.y2);
        ReduceDomain(img, ROI, &ROI_Img);
		Out_Img = img;
        //CropDomain(ROI_Img,&Out_Img);
        Threshold(ROI_Img, &Region, 0, 70);
        Connection (Region, &Region);
		ErosionCircle(Region, &Region, 2);
        //SelectShape(Region, &Region, "area","and", HTuple(100000), HTuple(1000000));

		SelectShapeStd(Region, &Region, "max_area", 70);
		DilationCircle(Region, &Region, 2);
		


		HObject RegionFillUp1, RegionDifference, RegionTrans, ImageReduced, Region1;
		HTuple Value1, Value2;
		Value1 = 0;
		Value2 = 0;
		FillUp(Region, &RegionFillUp1);
		HObject RegionDifference1;
		HTuple Value3;
		Value3 = 0;
		Difference(RegionFillUp1, Region, &RegionDifference);
		Connection(RegionDifference, &RegionDifference1);
		SelectShape(RegionDifference1, &RegionDifference1, "area","and", HTuple(100), HTuple(1000000));
		CountObj(RegionDifference1, &Value3);
	
		//纯石子
		if (Value3 == 0) 
		{
			OutRoundFlag = false;
			InRoundFlag = false;
			OutlenFlag = false;
			InlenFlag = false;
			CricleFlag = false;
			return 2;
		}
		HObject RegionDifference11;
		SelectShapeStd(RegionDifference1, &RegionDifference11, "max_area", 70);
		ShapeTrans(RegionDifference11, &RegionTrans, "outer_circle");
		ErosionCircle(RegionTrans, &RegionTrans, 7);
		ReduceDomain(img, RegionTrans, &ImageReduced);
		Threshold(ImageReduced, &Region1, 0, 100);
		RegionFeatures(Region1, "circularity", &Value1);
		RegionFeatures(Region1, "area", &Value2);
		double aaa = Value2.D();
		double xxx = Value1.D();
		if ((Value1 > 0.6)&&(Value2>300))
		{
			OutRoundFlag = false;
			InRoundFlag = false;
			OutlenFlag = false;
			InlenFlag = false;
			CricleFlag = false;
			return 2;
		}
				




		HTuple hv_Region_In;
		hv_Region_In = 0;
        Complement(Region,&RegionComplement);
        Connection(RegionComplement,&Region_In);
		SelectShape(Region_In, &Region_In, "circularity", "and", 0.8, 1);
		SelectShape(Region_In, &Region_In, "area", "and", 200, 1000000);
		SelectShapeStd(Region_In, &Region_In, "max_area", 70);
		Connection(Region_In, &Region_In);
		CountObj(Region_In, &hv_Region_In);
		if (hv_Region_In == 0)
		{
			OutRoundFlag = false;
			InRoundFlag = false;
			OutlenFlag = false;
			InlenFlag = false;
			CricleFlag = false;
			return 1;
		}

		HObject shitou;
		HTuple hv_shitou;
		hv_shitou = 0;
		ReduceDomain(img, Region_In, &shitou);
		Threshold(shitou, &shitou, 128, 255);
		RegionFeatures(shitou, "circularity", &hv_shitou);

        //SelectShape(Region_In, &Region_In, "area","and", HTuple(In_Circle_Size-3000), HTuple(In_Circle_Size+3000));
        RegionFeatures (Region_In, "circularity", &In_Round);
		//qDebug() << In_Round.D();
		double a= In_Round.D();

		FillUp(Region, &Region_Out);
        //SelectShape(RegionFillUp, &Region_Out, "area","and", HTuple(Out_Circle_Size-20000), HTuple(Out_Circle_Size+20000));
        RegionFeatures (Region_Out, "circularity", &Out_Round);
        AreaCenter(Region_Out,&Area, &Row, &Column);

        if(In_Round.D()>In_Roundness1)
        {
//            RegionFeatures (Region_In, "width", &Value_In);
//            In_Radius = Value_In/2;
//            In_Para.Clear();
//            In_Para.Append(Row).Append(Column).Append(0).Append(In_Radius).Append(In_Radius);

//            CreateMetrologyModel(&In_MetrologyHandle);

//            AddMetrologyObjectGeneric(In_MetrologyHandle, "ellipse", In_Para, 70, 5,
//                                      1, 30, HTuple(), HTuple(), &Index1);

//            ApplyMetrologyModel(ROI_Img, In_MetrologyHandle);

//            GetMetrologyObjectResult(In_MetrologyHandle, "all", "all", "result_type",
//                                     "all_param", &Parameter);
//            GetMetrologyObjectResultContour(&In_Contour, In_MetrologyHandle, "all",
//                                            "all", 1.5);
//            ClearMetrologyModel(In_MetrologyHandle);
//            AreaCenterXld(In_Contour, &In_Area, &In_Row, &In_Col, &PointOrder1);
//            CircularityXld(In_Contour, &In_Round);

            AreaCenter(Region_In,  &In_Area, &In_Row, &In_Col);
            GenContourRegionXld (Region_In, &In_Contour, "border");
            FitEllipseContourXld(In_Contour, "ftukey", -1, 2, 0, 200, 3, 2, &Row, &Column,
                                 &Phi, &In_Length1, &In_Length2, &StartPhi, &EndPhi, &PointOrder);
            In_Len =((Scale*(In_Length1 + In_Length2) / 2)+OffSet_In_Size) ;

            //检测内圆
//            GenRegionContourXld(In_Contour,&In_Region,"fill");
//            ErosionCircle(In_Region,&In_Region,2);
//            ReduceDomain(img,In_Region,&In_Region);
//            Threshold(In_Region,&In_Region,0,128);
//            Connection(In_Region,&In_Region);
//            SelectShape(In_Region,&S_In_Region,"area","and",200,999999);
//            CountObj(S_In_Region,&In_Num);

        }
        else
        {
             InCir= In_Round;
            Length_Error = 1;
        }


        if(Out_Round.D()>Out_Roundness1)
        {
//            RegionFeatures (Region_Out, "width", &Value_Out);
//            Out_Radius = Value_Out/2;
//            Out_Para.Clear();
//            Out_Para.Append(Row).Append(Column).Append(0).Append(Out_Radius).Append(Out_Radius);
//            CreateMetrologyModel(&Out_MetrologyHandle);


//            AddMetrologyObjectGeneric(Out_MetrologyHandle, "ellipse", Out_Para, 70,
//                                      5, 1, 30, HTuple(), HTuple(), &Index1);

//            ApplyMetrologyModel(ROI_Img, Out_MetrologyHandle);
//            GetMetrologyObjectResult(Out_MetrologyHandle, "all", "all", "result_type",
//                                     "all_param", &Parameter);
//            GetMetrologyObjectResultContour(&Out_Contour, Out_MetrologyHandle, "all",
//                                            "all", 1);
//            ClearMetrologyModel(Out_MetrologyHandle);
//            AreaCenterXld(Out_Contour, &Out_Area, &Out_Row, &Out_Col, &PointOrder);
//            CircularityXld(Out_Contour, &Out_Round);
            AreaCenter(Region_Out,  &Out_Area, &Out_Row, &Out_Col);
            GenContourRegionXld (Region_Out, &Out_Contour, "border");
            FitEllipseContourXld(Out_Contour, "ftukey", -1, 2, 0, 200, 3, 2, &Row,
                                 &Column, &Phi, &Out_Length1, &Out_Length2, &StartPhi, &EndPhi,
                                 &PointOrder);
            Out_Len =((Scale*(Out_Length1 + Out_Length2) / 2)+OffSet_Out_Size);
			

        }
        else
        {
            OutCir= Out_Round;
            Length_Error = 1;
        }
        Distance=sqrt(((Out_Row-In_Row).D()*(Out_Row-In_Row).D())+((Out_Col-In_Col).D()*(Out_Col-In_Col).D()))*Scale;

         //内圆度不合格
        if(!((In_Round.D()>In_Roundness2)))
        {
            InRoundFlag=false;
            Length_Error = 1;

        }
        //外圆度不合格
        if(!((Out_Round.D()>Out_Roundness2)))
        {
            OutRoundFlag=false;
            Length_Error = 1;

        }
		

        //内圆尺寸不合格
      

        if(!((In_Len.D()<(In_Size+Up_In_Deviation))&&(In_Len.D()>(In_Size-Down_In_Deviation))))
        {
            InlenFlag=false;
            Length_Error = 1;

        }
		
        //外圆尺寸不合格
        if(!((Out_Len.D()<(Out_Size+Up_Out_Deviation))&&(Out_Len.D()>(Out_Size-Down_Out_Deviation))))
        {
            OutlenFlag=false;
            Length_Error = 1;

        }
        //不同心
        if(Distance>Cricle_Deviation)
        {
            CricleFlag=false;
            Length_Error = 1;
        }
//        if(In_Num.D()!=0)
//        {
////            Length_Error = 1;
//        }

//        if(bSaveImage)
//        {
//            if(Length_Error==0)
//            {
//                if(m_nSaveOkImage){
//                    WriteImage(img,"bmp", 0, OK_Path.toStdString().c_str());
//                }

//            }
//            else
//            {
//                 WriteImage(img,"bmp", 0, NG_Path.toStdString().c_str());
//            }

//        }
		////表明有石子
		//if (In_Len.D() < (In_Size - Down_In_Deviation)|| (hv_shitou.D()< In_Roundness1))
		//{
		//	InlenFlag = false;
		//	Length_Error = 2;
		//}
        return Length_Error;
    }

    catch(HException &exception)
    {
        Length_Error=2;
        OutRoundFlag=false;
        InRoundFlag=false;
        OutlenFlag=false;
        InlenFlag=false;
        CricleFlag=false;
        if(bSaveImage)
        {
            WriteImage(img,"bmp", 0, Abnormal_Path.toStdString().c_str());
        }
        return Length_Error;
    }
}
















